# gui/main_window.py - Main application window

import os
import sys
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
                             QPushButton, QFileDialog, QLabel, QListWidget,
                             QTabWidget, QMessageBox, QComboBox, QGroupBox,
                             QCheckBox, QSpinBox, QSplitter)
from PyQt5.QtCore import Qt, QThreadPool, pyqtSlot

from gui.video_player import VideoPlayer
from gui.progress_bar import ProgressBar
from gui.event_editor import EventEditor
from video_processing.processing_worker import VideoProcessingWorker
from data_storage.database import Database
from data_storage.export_data import export_to_json, export_to_csv


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Football Video Cutter")
        self.resize(1200, 800)

        # Initialize database
        self.db = Database()

        # Initialize thread pool for worker threads
        self.thread_pool = QThreadPool()
        self.thread_pool.setMaxThreadCount(os.cpu_count() or 4)

        # Set up the UI
        self._setup_ui()

        # Store video files and events
        self.video_files = []
        self.detected_events = []

    def _setup_ui(self):
        """Set up the main user interface"""
        # Main widget and layout
        main_widget = QWidget()
        main_layout = QVBoxLayout()
        main_widget.setLayout(main_layout)
        self.setCentralWidget(main_widget)

        # Create a horizontal splitter
        splitter = QSplitter(Qt.Horizontal)
        main_layout.addWidget(splitter)

        # Left panel for controls
        left_panel = QWidget()
        left_layout = QVBoxLayout(left_panel)

        # Video selection group
        video_group = QGroupBox("Video Selection")
        video_layout = QVBoxLayout()

        # Video import buttons
        import_btn = QPushButton("Import Videos")
        import_btn.clicked.connect(self.import_videos)
        video_layout.addWidget(import_btn)

        # Videos list
        self.video_list = QListWidget()
        video_layout.addWidget(self.video_list)

        video_group.setLayout(video_layout)
        left_layout.addWidget(video_group)

        # Settings group
        settings_group = QGroupBox("Detection Settings")
        settings_layout = QVBoxLayout()

        # Detection options
        self.detect_stadium = QCheckBox("Stadium Shots")
        self.detect_stadium.setChecked(True)
        settings_layout.addWidget(self.detect_stadium)

        self.detect_shots = QCheckBox("Goal Shots")
        self.detect_shots.setChecked(True)
        settings_layout.addWidget(self.detect_shots)

        self.detect_celebration = QCheckBox("Celebration Shots")
        self.detect_celebration.setChecked(True)
        settings_layout.addWidget(self.detect_celebration)

        # Detection sensitivity
        sens_layout = QHBoxLayout()
        sens_layout.addWidget(QLabel("Sensitivity:"))
        self.sensitivity = QSpinBox()
        self.sensitivity.setRange(1, 10)
        self.sensitivity.setValue(5)
        sens_layout.addWidget(self.sensitivity)
        settings_layout.addLayout(sens_layout)

        # Thread count
        thread_layout = QHBoxLayout()
        thread_layout.addWidget(QLabel("Threads:"))
        self.thread_count = QSpinBox()
        self.thread_count.setRange(1, os.cpu_count() or 4)
        self.thread_count.setValue(os.cpu_count() // 2 if os.cpu_count() else 2)
        thread_layout.addWidget(self.thread_count)
        settings_layout.addLayout(thread_layout)

        settings_group.setLayout(settings_layout)
        left_layout.addWidget(settings_group)

        # Process control group
        process_group = QGroupBox("Process Control")
        process_layout = QVBoxLayout()

        # Start processing button
        self.start_btn = QPushButton("Start Processing")
        self.start_btn.clicked.connect(self.start_processing)
        process_layout.addWidget(self.start_btn)

        # Progress bar
        self.progress = ProgressBar()
        process_layout.addWidget(self.progress)

        # Export buttons
        export_layout = QHBoxLayout()

        self.export_json_btn = QPushButton("Export JSON")
        self.export_json_btn.clicked.connect(self.export_json)
        export_layout.addWidget(self.export_json_btn)

        self.export_csv_btn = QPushButton("Export CSV")
        self.export_csv_btn.clicked.connect(self.export_csv)
        export_layout.addWidget(self.export_csv_btn)

        process_layout.addLayout(export_layout)

        process_group.setLayout(process_layout)
        left_layout.addWidget(process_group)

        splitter.addWidget(left_panel)

        # Right panel with tabs
        right_panel = QTabWidget()

        # Video player tab
        self.video_player = VideoPlayer()
        right_panel.addTab(self.video_player, "Video Player")

        # Events editor tab
        self.event_editor = EventEditor(self.db)
        self.event_editor.event_updated.connect(self.on_event_updated)
        right_panel.addTab(self.event_editor, "Event Editor")

        splitter.addWidget(right_panel)

        # Set initial splitter sizes
        splitter.setSizes([400, 800])

    def import_videos(self):
        """Open file dialog to import videos"""
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.ExistingFiles)
        file_dialog.setNameFilter("Video files (*.mp4 *.avi *.mkv *.mov)")

        if file_dialog.exec_():
            filenames = file_dialog.selectedFiles()
            self.video_files.extend(filenames)

            # Clear and update the video list
            self.video_list.clear()
            for file in self.video_files:
                self.video_list.addItem(os.path.basename(file))

    def start_processing(self):
        """Start video processing with the selected settings"""
        if not self.video_files:
            QMessageBox.warning(self, "No Videos", "Please import videos first.")
            return

        # Collect settings
        settings = {
            "detect_stadium": self.detect_stadium.isChecked(),
            "detect_shots": self.detect_shots.isChecked(),
            "detect_celebration": self.detect_celebration.isChecked(),
            "sensitivity": self.sensitivity.value(),
            "thread_count": self.thread_count.value()
        }

        # Disable buttons during processing
        self.start_btn.setEnabled(False)

        # Create worker for processing
        worker = VideoProcessingWorker(self.video_files, settings, self.db)
        worker.signals.progress.connect(self.progress.set_progress)
        worker.signals.result.connect(self.processing_finished)
        worker.signals.error.connect(self.processing_error)
        worker.signals.event_detected.connect(self.event_detected)

        # Execute
        self.thread_pool.start(worker)

    @pyqtSlot(dict)
    def event_detected(self, event):
        """Handle a new detected event"""
        self.detected_events.append(event)
        self.event_editor.add_event(event)

    @pyqtSlot(dict)
    def on_event_updated(self, event):
        """Handle updated event from the event editor"""
        # Find and update the event in our list
        for i, e in enumerate(self.detected_events):
            if e['id'] == event['id']:
                self.detected_events[i] = event
                break

    @pyqtSlot(list)
    def processing_finished(self, results):
        """Handle processing completion"""
        self.start_btn.setEnabled(True)
        self.progress.set_progress(100)
        QMessageBox.information(self, "Processing Complete",
                                f"Processed {len(self.video_files)} videos.\n"
                                f"Found {len(self.detected_events)} events.")

    @pyqtSlot(str)
    def processing_error(self, error):
        """Handle processing errors"""
        self.start_btn.setEnabled(True)
        QMessageBox.critical(self, "Processing Error", error)

    def export_json(self):
        """Export events to JSON file"""
        if not self.detected_events:
            QMessageBox.warning(self, "No Events", "No events to export.")
            return

        file_path, _ = QFileDialog.getSaveFileName(
            self, "Export JSON", "", "JSON Files (*.json)")

        if file_path:
            try:
                export_to_json(self.detected_events, file_path)
                QMessageBox.information(self, "Export Successful",
                                        f"Exported {len(self.detected_events)} events to {file_path}")
            except Exception as e:
                QMessageBox.critical(self, "Export Failed", str(e))

    def export_csv(self):
        """Export events to CSV file"""
        if not self.detected_events:
            QMessageBox.warning(self, "No Events", "No events to export.")
            return

        file_path, _ = QFileDialog.getSaveFileName(
            self, "Export CSV", "", "CSV Files (*.csv)")

        if file_path:
            try:
                export_to_csv(self.detected_events, file_path)
                QMessageBox.information(self, "Export Successful",
                                        f"Exported {len(self.detected_events)} events to {file_path}")
            except Exception as e:
                QMessageBox.critical(self, "Export Failed", str(e))